﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Globalization;

namespace MipsPipelineSimulator
{
    public partial class RegisterControl : UserControl
    {
        public RichListView registerListView = null;

        public RegisterControl()
        {
            InitializeComponent();

            registerListView = new RichListView(2, false);
            ColumnHeader name = new ColumnHeader();
            name.Text = "寄存器名称";
            name.Width = this.Width / 2 - 40;
            ColumnHeader value = new ColumnHeader();
            value.Text = "寄存器值";
            value.Width = this.Width / 2;
            registerListView.Columns.AddRange(new ColumnHeader[2] { name, value });
            this.Controls.Add(registerListView);

            registerListView.SetColumnEditable(2, new RichListView.validate(this.validateValue));

            for (int i = 0; i < 32; i++)
            {
                string[] s = new string[2];
                s[0] = "R" + i.ToString(); ;
                s[1] = "0000000000000000";
                registerListView.Items.Add(new ListViewItem(s));
            }

            for (int i = 0; i < 32; i++)
            {
                string[] s = new string[2];
                s[0] = "F" + i.ToString(); ;
                s[1] = "0000000000000000";
                registerListView.Items.Add(new ListViewItem(s));
            }
        }

        public RichListView RichListView
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        private void RegisterControl_Load(object sender, EventArgs e)
        {
           
        }

        public bool validateValue(string inputStr)
        {
            Regex r = new Regex(@"[0-9A-Fa-f]{16}$");
            return r.Match(inputStr).Success;
        }

        public bool IfExsit(String registerName)
        {
            ListViewItem register = registerListView.FindItemWithText(registerName, false, 0);
            if (register == null) return false;
            else return true;
        }

        public String GetRegisterValue(String registerName)
        {
            ListViewItem register = registerListView.FindItemWithText(registerName, false, 0);
            if (register == null) return null;
            else{
                return register.SubItems[1].Text;
            }
        }

        public bool SetRegisterValue(String registerName, String registerValue)
        {
            ListViewItem register = registerListView.FindItemWithText(registerName, false,0);
            if (register == null) return false;
            else
            {
                register.SubItems[1].Text = registerValue;
                return true;
            }
        }

        public bool SetRegisterValue(String registerName, object value, TypeCode type)
        {
            switch(type)
            {
                case TypeCode.Int32:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.Int32, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 8, 8);
                    }
                case TypeCode.UInt32:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.UInt32, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 8, 8);
                    }
                case TypeCode.Int64:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.Int64, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 0, 16);
                    }
                case TypeCode.UInt64:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.UInt64, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 0, 16);
                    }
                case TypeCode.Int16:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.Int16, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 12, 4);
                    }
                case TypeCode.UInt16:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.UInt16, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 12, 4);
                    }
                case TypeCode.SByte:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.SByte, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 14, 2);
                    }
                case TypeCode.Byte:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.Byte, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 14, 2);
                    }
                case TypeCode.Single:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.Single, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 8, 8);
                    }
                case TypeCode.Double:
                    {
                        string valueStr = CommonTool.NumToStr(TypeCode.Double, value, "X", true);
                        return this.SetRegisterValue(registerName, valueStr, 0, 16);
                    }
            }
            return false;
        }

        private bool SetRegisterValue(String registerName, String registerValue, int index, int count)
        {
            ListViewItem register = registerListView.FindItemWithText(registerName, false, 0);
            if (register == null) return false;
            else
            {
                register.SubItems[1].Text = register.SubItems[1].Text.Remove(index, count).Insert(index, registerValue);
                return true;
            }
        }
    }
}
